home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / music4c.sit / Music4C Folder / Sources Folder / gen.c < prev    next >
Text File  |  1990-09-08  |  13KB  |  652 lines

  1. /*
  2. * ⌐ Graeme Gerrard 1990
  3. * Faculty of Music, University of Melbourne
  4. * Parkville Victoria 3052 Australia.
  5. *
  6. * ARPANET: grae@murdu.ucs.unimelb.edu.au
  7. * telephone: (613) 344 4127, Fax: (613) 344 5346
  8. */
  9.  
  10.  
  11. #include    "Music4C.h"
  12. #include    "Music4C_Prototype.h"
  13. #include    "ErrorAlert.h"
  14. #include    <math.h>
  15. #define        TWOPI    6.283185308
  16.  
  17. #define        ADD            1
  18. #define        SUBTRACT    2
  19. #define        MULTIPLY    3
  20. #define        DIVIDE        4
  21.  
  22. #define    ABS(x)    ((x) >= 0.0 ? (x) : -(x))
  23.  
  24. double    *F[MAXFUNCS];
  25. Boolean    defined_funcs[MAXFUNCS];
  26. static    int        scale_flag;
  27. extern    OSErr    theErr;
  28.  
  29. extern    void    init_funcs(void);
  30. extern    void    free_funcs(void);
  31. extern    void    gen(int, double *);
  32. extern    Str255    theMess1, theMess2;
  33. extern    write_func(int, double *);
  34.  
  35. void    gen2(int, double *, double *);
  36. void    gen5(int, double *, double *);
  37. void    gen6(int, double *, double *);
  38. void    gen7(int, double *, double *);
  39. void    gen9(int, double *, double *);
  40. void    gen10(int, double *, double *);
  41. void    gen11(int, double *, double *);
  42. void    gen12(int, double *, double *);
  43. void    gen20(int, double *, double *);
  44.  
  45. void    fnscl(double *, int);
  46.  
  47.  
  48.  
  49.  
  50. void    init_funcs()
  51. {
  52.     register int i;
  53.     Boolean    *bp;
  54.     for ( i = 0, bp = defined_funcs; i< MAXFUNCS; i++) {
  55.         *bp++ = FALSE;
  56.     }
  57. }
  58.  
  59. void    free_funcs()
  60. {
  61.     register int i;
  62.     for ( i = 0; i< MAXFUNCS; i++) {
  63.         if (defined_funcs[i] ) {
  64.             DisposPtr((Ptr)F[i]);
  65.         defined_funcs[i] = FALSE;
  66.         }
  67.     }
  68. }
  69.  
  70. void    gen(npargs, p)
  71.     double *p;
  72.     int npargs;
  73. {
  74.     register    long    i;
  75.     extern    char        aString1[256];
  76.     extern    char        aString2[256];
  77.     int genno;
  78.     int genraw;
  79.     int print_switch = 0;
  80.     int    len;
  81.     int    fno;
  82.  
  83.     genraw = (int) *(p+2);
  84.     genno = genraw % 100;
  85.     scale_flag = 1;
  86.     switch( genraw - genno) {
  87.         case 0:
  88.             break;
  89.         case 100:
  90.                 print_switch = 1;
  91.                 break;
  92.         case 200:
  93.                 scale_flag = 0;
  94.                 break;
  95.         default:
  96.             sprintf(aString1, "unknown gen switch %d", (genraw - genno));
  97.             CtoPstr(aString1);
  98.             sprintf(aString2, "for function no. %d", (int) *p);
  99.             CtoPstr(aString2);
  100.             PstringCopy((char *)theMess1, (char *)aString1);
  101.             PstringCopy((char *)theMess2, (char *)aString2);
  102.             OSError(theMess1, theMess2, NIL);
  103.     }
  104.  
  105.     fno = (int) *p;
  106.     len = *(p+3);
  107.     if (defined_funcs[ (int) *p] ) {
  108.         /* i.e. already defined, free space and redefine it if different size */
  109.         if (len == (int)*F[fno])
  110.             /* same size, do nothing */
  111.             ;
  112.         else { /* different size */
  113.             DisposPtr((Ptr)F[fno]);
  114.     /* reset this, so that func gets redefined in next code block */
  115.             defined_funcs[fno] = FALSE;
  116.         }
  117.     }
  118.     
  119.     if ( !defined_funcs[fno] ) {
  120.         defined_funcs[fno] = TRUE;
  121.         F[fno] = (double *) NewPtr( (len+1) * sizeof(double));
  122.         if ( (theErr = MemError())  != noErr ){
  123.             PstringCopy((char *)theMess1, "\pError allocating memory in gen");
  124.             OSError(theMess1, NIL, NIL);
  125.         }
  126.         *F[fno] = (double)len;
  127.         for ( i = 1; i < len+1; i ++ )
  128.             *(F[fno]+i) = 0.0;
  129.     }
  130.     switch( ABS(genno) ) {
  131.         case 2:
  132.             if ( len != 512 ) {
  133.                 PstringCopy((char *)theMess1, "\pFunctions generated by gen2 must be 512 long");
  134.                 OSError(theMess1, NIL, NIL);
  135.             }
  136.             gen2(npargs, p, F[fno]);
  137.             break;
  138.         case 5:
  139.             gen5(npargs, p, F[fno]);
  140.             break;
  141.         case 7:
  142.             gen7(npargs, p, F[fno]);
  143.             break;
  144.         case 9:
  145.             gen9(npargs, p, F[fno]);
  146.             break;
  147.         case 11:
  148.             gen11(npargs, p, F[fno]);
  149.             break;
  150.         case 12:
  151.             gen12(npargs, p, F[fno]);
  152.             break;
  153.         case 20:
  154.             gen20(npargs, p, F[fno]);
  155.             break;
  156.         default:
  157.             sprintf((char *)aString1, "Error generating function number %d", fno );
  158.             CtoPstr((char *)aString1);
  159.             sprintf((char *)aString2, "gen function %d unknown", genno);
  160.             CtoPstr((char *)aString2);
  161.             PstringCopy((char *)theMess1, (char *)aString1);
  162.             PstringCopy((char *)theMess2, (char *)aString2);
  163.             OSError(theMess1, theMess2, NIL);
  164.     }
  165.     if ( print_switch )
  166.         write_func(fno, F[fno] );
  167.         
  168.             
  169. }
  170.  
  171.  
  172.  
  173. void    gen2(npargs, p, f)
  174.     double *p, *f;
  175.     int npargs;
  176. {
  177.     register    long    i;
  178.     register    long    k;
  179.     register    long    j;
  180.     register    long    l;
  181.     register    long    lv;
  182.     register    long    lj;
  183.     int    incr;
  184.     double    z;
  185.     double    xint;
  186.     
  187.     z = p[2] - (int)p[2];
  188.     p[2] = p[2] - z;
  189.     if ( z <= 0.0 ) {
  190.         gen6(npargs, p, f);
  191.         if ( p[2] < 0.0 ) {
  192.             incr = 2;
  193.             for ( i = 2; i <= 512; i += 2 ) *(f+i) = 0.0;
  194.             k = 1;
  195.             for ( l = 2; l <=171; l++ ) {
  196.                 k += 2;
  197.                 if ( *(f+k) != 0.0 ) {
  198.                     *(f+l) = *(f+k);
  199.                     *(f+k) = 0.0;
  200.                 }
  201.                 else {
  202.                     lv = l - 1;
  203.                     goto L40;
  204.                 }
  205.             }
  206.             for ( i = 171; i <= 512; i += incr ) *(f+i) = 0.0;
  207.         }
  208.     }
  209.     else {
  210.         /* change order of p args */
  211.         for ( l = npargs; l > 1; l-- )
  212.             p[l] = p[l-1];
  213.         gen5(npargs+1, p, f);
  214.         xint = 100.0 / 12.0 * z;
  215.         incr = 1;
  216.         for ( l = 2; l <=171; l++ ) {
  217.             if ( *(f+l) == 0.0 ) {
  218.                 lv = l - 1;
  219.                 goto L40;
  220.             }
  221.         }
  222.         for ( l = 171; i <= 512; l += incr ) *(f+l) = 0.0;
  223.         lv = 170;
  224.     }
  225. L40:
  226.     lj = 3 * lv - 1;
  227.     for ( i = 2; i <= lj; i += 3 ) {
  228.         j = lj + 2 - i;
  229.         *(f+j) = *(f+lv);
  230.         lv--;
  231.         if ( z <= 0.0 )
  232.             *(f+j-1) = 1 + lv * incr;
  233.         else
  234.             *(f+j-1) = ((int)( 128.0 * pow(2.0, (lv*xint)) )) / 128.0;
  235.         *(f+j+1) = 0.0;
  236.     }
  237. }
  238.  
  239.  
  240. void    gen5(npargs, p, f)
  241.     double *p, *f;
  242.     int npargs;
  243. {
  244.     register int i;
  245.     int len = *f;
  246.     int j, k, l, m, n;
  247.     double x1, y1, x2, y2;
  248.     double c;
  249.  
  250.  
  251.     y2 = *(p+5);
  252.     i = 1;
  253.  
  254.     n = 6;
  255.     while (n < npargs) {
  256.         if ( *(p+n+1) <= 0.0 )
  257.             break;
  258.         y1 = y2;
  259.         y2 = *(p+n+1);
  260.         j = i;
  261.         if ( j > len )
  262.             break;
  263.         *(f+j) = y1;
  264.         m = j + 1;
  265.         i = *(p+n);
  266.         j = i - j;
  267.         if ( m <= i ) {
  268.             c = pow( (y2/y1), (1.0/j));
  269. /*            c = pow( (y2/y1), (1.0/(*(p+n))));*/
  270.             for ( l = m; l < i; l++ )
  271.                 *(f+l) = *(f+l-1) * c;
  272.         }
  273.         n += 2;
  274.     }
  275.     *(f+i) = y2;
  276.     fnscl(f, len);
  277. }
  278.  
  279.  
  280.  
  281. void    gen6(npargs, p, f)
  282.     double *p, *f;
  283.     int npargs;
  284. {
  285.     register    long    i;
  286.     register    long    k;
  287.     register    long    l;
  288.     register    long    j;
  289.     int    len;
  290.     double    xj;
  291.     double    vratio;
  292.     double    amp1;
  293.     double    amp2;
  294.     double    base;
  295.     len = (int)*f;
  296.     
  297.     for ( i = 1; i < len+1; i++ ) *(f+i) = 0.0;
  298.     
  299.     i = 0;
  300.     amp2 = p[4];
  301.     for ( k = 5; k < npargs; k += 2 ) {
  302.         if ( p[k] > 0.0 ) {
  303.             amp1 = amp2;
  304.             amp2 = p[k+1];
  305.             j = i + 1;
  306.             i = j + p[k] - 1;
  307.             xj = j;
  308.             vratio = amp2 / amp1;
  309.             base = log( (i+1) / xj );
  310.             for ( l = j; l <= i; l++ ) {
  311.                 if ( l <= len )
  312.                     *(f+l) = amp1 * pow(vratio, (log(l/xj) / base));
  313.                 else
  314.                     break;
  315.             }
  316.         }
  317.         else
  318.             break;
  319.     }
  320.     fnscl(f, len);
  321. }
  322.     
  323.     
  324. void    gen7(npargs, p, f)
  325.     double *p, *f;
  326.     int npargs;
  327. {
  328. /* straight line segments */
  329. /*    p4 = 1st x value
  330.     p5 = 1st y value
  331.     p6 = 2nd x value
  332.     p7 = 2nd y value
  333.     etc.
  334. */
  335.     register int     i;
  336.     register int     n;
  337.     int len = *f;
  338.     int j, k;
  339.     double x1, y1, x2, y2;
  340.     double x_diff, y_diff;
  341.  
  342.  
  343.     y2 = *(p+5);
  344.     x2 = *(p+4);
  345.  
  346.     n = 6;
  347.     while (n < npargs) {
  348.         x1 = x2;
  349.         x2 = *(p+n);
  350.         y1 = y2;
  351.         y2 = *(p+n+1);
  352.         y_diff = y2 - y1;
  353.         x_diff = x2 - x1;
  354.         j = (int)x1;
  355.         if ( j < 1 )
  356.             j = 1;
  357.         k = (int)x2;
  358.         for ( i = j; i<=k; i++)
  359.             *(f+i) = y1 + (y_diff *((i - x1)/x_diff));
  360.         n += 2;
  361.     }
  362.     *(f+(int)x2) = y2;
  363.     if ( scale_flag )
  364.         fnscl(f, len);
  365. }
  366.  
  367.  
  368. void    gen9(npargs, p, f)
  369.     double *p, *f;
  370.     int npargs;
  371. {
  372. /*
  373. *(p+4) = partial no, *(p+5) = amplitude, *(p+6) = phase in degrees
  374. */
  375.     register int     i;
  376.     register int     n;
  377.     int len = *f;
  378.     double arg;
  379.     double rads;
  380.     double hno;
  381.     double amp;
  382.     double phs;
  383.  
  384.  
  385.     rads = TWOPI/len;
  386.     for ( n = 4; n < npargs; n += 3 ) {
  387.         hno = *(p+n);
  388.         amp = *(p+n+1);
  389.         phs = (*(p+n+2) * len) / 360.0; 
  390.  
  391.         if ( hno == 0.0 )
  392.             break;
  393.  
  394.         for ( i = 1; i < len+1; i++ ) {
  395.             *(f+i) += (amp * sin(rads * ((i-1) * hno + phs)));
  396.         }
  397.     }
  398.     fnscl(f, len);
  399. }
  400.  
  401.  
  402. void    gen10(npargs, p, f)
  403.     double *p, *f;
  404.     int npargs;
  405. {
  406. /*
  407. *(p+4) = amp of harmonic no 1,
  408. *(p+5) = amp of harmonic no 2,
  409. *(p+6) = amp of harmonic no 3, etc.
  410. */
  411.     register int     i;
  412.     register int     n;
  413.     int len = *f;
  414.     double arg;
  415.     double rads;
  416.     double hno;
  417.     double amp;
  418.  
  419.  
  420.     rads = TWOPI/len;
  421.     for ( n = 4; n < npargs; n += 3 ) {
  422.         hno = n-3;
  423.         amp = *(p+n+1);
  424.         if ( hno == 0.0 )
  425.             break;
  426.         for ( i = 1; i < len+1; i++ )
  427.             *(f+i) += (amp * sin(rads * ((i-1) * hno)));
  428.     }
  429.     fnscl(f, len);
  430. }
  431.  
  432. void    gen11(npargs, p, f)
  433.     double *p, *f;
  434.     int npargs;
  435. {
  436. /* just copies arguments into F */
  437.     register int     i;
  438.     register int     n;
  439.     int len = *f;
  440.  
  441.  
  442.     n = 4;
  443.     for ( i = 1; i < len+1; i++ ) {
  444.         *(f+i) = *(p+n);
  445.         n++;
  446.     }
  447.     if ( scale_flag )
  448.         fnscl(f, len);
  449. }
  450.  
  451. void    gen12(npargs, p, f)
  452.     double *p, *f;
  453.     int npargs;
  454. {
  455. /* combines two functions */
  456. /*    *(p+4) = first function no
  457.     *(p+5) = start location in first function
  458.     *(p+6) = end location in first function
  459.     *(p+7) = second function no.
  460.             if positive with no fractional part = add the two functions.
  461.             if negative with no fractional part = subtract this function
  462.                 from the first function.
  463.             if positive with fractional part = multiply the two functions.
  464.             if negative with fractional part = divide the first function
  465.                 by the second function.
  466.     *(p+8) = start location in second function
  467.     *(p+9) = end location in second function
  468. */
  469.     register int     i;
  470.  
  471.     int len = *f;
  472.     int    fno1, fno2;
  473.     int    len1, len2;
  474.     int    start1, end1, start2, end2;
  475.     int    theOp;
  476.     /* get function numbers */
  477.     fno1 = ABS(*(p+4));
  478.     fno2 = ABS(*(p+7));
  479.     /* check they are both defined */
  480.     if ( !defined_funcs[fno1]) {
  481.         sprintf(aString1, "Attempt to access undefined function %d in gen12", fno1);
  482.         CtoPstr(aString1);
  483.         sprintf(aString2, "function no. %d", (int) *p);
  484.         CtoPstr(aString2);
  485.         PstringCopy((char *)theMess1, (char *)aString1);
  486.         PstringCopy((char *)theMess2, (char *)aString2);
  487.         OSError(theMess1, theMess2, NIL);
  488.     }
  489.     if ( !defined_funcs[fno2]) {
  490.         sprintf(aString1, "Attempt to access undefined function %d in gen12", fno2);
  491.         CtoPstr(aString1);
  492.         sprintf(aString2, "function no. %d", (int) *p);
  493.         CtoPstr(aString2);
  494.         PstringCopy((char *)theMess1, (char *)aString1);
  495.         PstringCopy((char *)theMess2, (char *)aString2);
  496.         OSError(theMess1, theMess2, NIL);
  497.     }
  498.     /* get here if both functions are defined, figure out operation */
  499.     if ( *(p+7) > 0.0) {
  500.         if ( (*(p+7) - (int)*(p+7)) == 0.0 )
  501.             theOp = ADD;
  502.         else
  503.             theOp = MULTIPLY;
  504.     }
  505.     else if ( *(p+7) < 0.0) {
  506.         if ( (*(p+7) - (int)*(p+7)) == 0.0 )
  507.             theOp = SUBTRACT;
  508.         else
  509.             theOp = DIVIDE;
  510.     }
  511.     /* get start and end bounds */
  512.     start1 = (int)*(p+5);
  513.     end1 = (int)*(p+6);
  514.     start2 = (int)*(p+8);
  515.     end2 = (int)*(p+9);
  516.     if ( start1 > *F[fno1] || start1 < 1) {
  517.         sprintf(aString1, "gen12, bad start location %d in first function", start1);
  518.         CtoPstr(aString1);
  519.         PstringCopy((char *)theMess1, (char *)aString1);
  520.         OSError(theMess1, NIL, NIL);
  521.     }
  522.     if ( end1 > *F[fno1] || end1 < 1) {
  523.         sprintf(aString1, "gen12, bad end location %d in first function", end1);
  524.         CtoPstr(aString1);
  525.         PstringCopy((char *)theMess1, (char *)aString1);
  526.         OSError(theMess1, NIL, NIL);
  527.     }
  528.     if ( start2 > *F[fno2] || start2 < 1) {
  529.         sprintf(aString1, "gen12, bad start location %d in second function", start2);
  530.         CtoPstr(aString1);
  531.         PstringCopy((char *)theMess1, (char *)aString1);
  532.         OSError(theMess1, NIL, NIL);
  533.     }
  534.     if ( start2 > *F[fno2] || end2 < 1) {
  535.         sprintf(aString1, "gen12, bad end location %d in second function", end2);
  536.         CtoPstr(aString1);
  537.         PstringCopy((char *)theMess1, (char *)aString1);
  538.         OSError(theMess1, NIL, NIL);
  539.     }
  540.     
  541.     
  542. /* assume that lengths are the same, we'll add expansion and contraction later */
  543.     for ( i = start1; i <= end1; i++ ) {
  544.         switch (theOp ) {
  545.             case ADD:
  546.                 *(f+i) = *(F[fno1]+i) + *(F[fno2]+i);
  547.                 break;
  548.             case SUBTRACT:
  549.                 *(f+i) = *(F[fno1]+i) - *(F[fno2]+i);
  550.                 break;
  551.             case MULTIPLY:
  552.                 *(f+i) = *(F[fno1]+i) * *(F[fno2]+i);
  553.                 break;
  554.             case DIVIDE:
  555.                 if (*(F[fno2]+i) != 0.0 )
  556.                     *(f+i) = *(F[fno1]+i) - *(F[fno2]+i);
  557.                 else
  558.                     *(f+i) = *(F[fno1]+i);
  559.                 break;
  560.         }
  561.     }
  562.     
  563.     if ( scale_flag )
  564.         fnscl(f, len);
  565. }
  566.  
  567.  
  568. void    gen20(npargs, p, f)
  569.     double *p, *f;
  570.     int npargs;
  571. {
  572. /* reads in a file of floating point values */
  573.     register    i;
  574.     int len = *f;
  575.     SFReply        reply;
  576.     SFTypeList    types;
  577.     Point        where;
  578.     float        *theFloats;
  579.     int            theRefNum;
  580.     long        count;
  581.     
  582.     SetPt(&where, 100, 100);
  583.     SFGetFile(where, NIL, NIL, -1, NIL, NIL, &reply);
  584.     if(!reply.good) {
  585.         return;
  586.     }
  587.     count = (float)len * sizeof(float);
  588.     theFloats = (float *) NewPtr(sizeof(float) * len);
  589.     if ( (theErr = MemError())  != noErr ){
  590.         PstringCopy((char *)theMess1, "\pError allocating memory in gen20");
  591.         OSError(theMess1, NIL, NIL);
  592.     }
  593.     theErr = FSOpen(reply.fName, reply.vRefNum, &theRefNum);
  594.     theErr = FSRead(theRefNum, &count, theFloats);
  595.     theErr = FSClose(theRefNum);
  596.     if ( theErr != noErr ) {
  597.         DisposPtr((Ptr)theFloats);
  598.         return;
  599.     }
  600.  
  601.     len = (count/sizeof(long));
  602.     for ( i = 1; i < len+1; i++ )
  603.         *(f+i) = (double)theFloats[i-1];
  604.         
  605.     if ( scale_flag )
  606.         fnscl(f, len);
  607.     DisposPtr((Ptr)theFloats);
  608. }
  609.  
  610.  
  611. write_func(fno, f)
  612.     double *f;
  613.     int fno;
  614. {
  615.     extern        char        theMessage[MAXSTRING];
  616.     extern    int    out3_flag;
  617.     register int i;
  618.     int len = *f;
  619.  
  620.     if ( out3_flag ) {
  621.         sprintf((char *)theMess1, "Function no. %d length is  %d", fno, len );
  622.         Report((char *)theMess1);
  623.         for ( i = 1; i < len+1; i++ ) {
  624.             sprintf((char *)theMess1, "%d %f\n", i, *(f+i) );
  625.             Report((char *)theMess1);
  626.         }
  627.         Report("-----------------------------------\n");
  628.     }
  629. }
  630.  
  631.  
  632.  
  633. void    fnscl(f, len)
  634.     double *f;
  635.     int len;
  636. {
  637.     register int i;
  638.     double wmax,xmax = 0;
  639.  
  640.     for(i = 1; i < len+1; i++ ) {
  641.         if ((wmax = fabs(*(f+i))) > xmax) xmax = wmax;
  642.     }
  643.     for(i = 1; i < len+1; i++ ) {
  644.         *(f+i) /= xmax;
  645.     }
  646. }
  647.  
  648.  
  649. /*-------------------------------------------------------------------------------*/
  650.  
  651.  
  652.